/*
 * @Copyright (c) 2018 缪聪(mcg-helper@qq.com)
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");  
 * you may not use this file except in compliance with the License.  
 * You may obtain a copy of the License at  
 *     
 *     http://www.apache.org/licenses/LICENSE-2.0  
 *     
 * Unless required by applicable law or agreed to in writing, software  
 * distributed under the License is distributed on an "AS IS" BASIS,  
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
 * See the License for the specific language governing permissions and  
 * limitations under the License.
 */

package com.mcgrobot.plugin.schedule;

import java.util.ArrayList;
import java.util.List;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import com.alibaba.fastjson.JSON;
import com.mcgrobot.common.SpringContextHelper;
import com.mcgrobot.service.STimetaskService;

public class InitQuartzJob {
	private static final Logger logger = LoggerFactory.getLogger(InitQuartzJob.class);
	public static SchedulerFactoryBean schedulerFactoryBean = null;
 
	public static void init() {
		schedulerFactoryBean = (SchedulerFactoryBean) SpringContextHelper.getSpringBean(SchedulerFactoryBean.class);

		STimetaskService sTimetaskService = (STimetaskService) SpringContextHelper.getSpringBean(STimetaskService.class);
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		try {
			logger.info(scheduler.getSchedulerName());

			// 这里从数据库中获取任务信息数据
			List<STimetask> list = sTimetaskService.queryAll();
		
			List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();
			
			for (STimetask sTimetask : list) {
				if(!"1".equals(sTimetask.getPlanStatus())) {
					continue ;
				}
				ScheduleJob scheduleJob = new ScheduleJob();
				scheduleJob.setJobId(sTimetask.getTaskId());
				scheduleJob.setJobGroup(sTimetask.getGroupName()); // 任务组
				scheduleJob.setJobName(sTimetask.getName());// 任务名称
				scheduleJob.setJobStatus(sTimetask.getPlanStatus()); // 任务发布状态
				scheduleJob.setIsConcurrent(sTimetask.getIsConcurrent() == 1 ? "1" : "0");
				scheduleJob.setCronExpression(sTimetask.getCron());
				scheduleJob.setBeanClass(sTimetask.getBeanName());// 一个以所给名字注册的bean的实例
				scheduleJob.setMethodName(sTimetask.getMethodName());
				scheduleJob.setJobData(sTimetask.getJobData()); // 参数
				
				jobList.add(scheduleJob);
			}
	 
			for (ScheduleJob job : jobList) {
				
				addJob(job);
			}
		} catch (SchedulerException e) {
			logger.error("调度初始化失败：", e);
		}
	}
 
	/**
	 * 添加任务
	 * 
	 * @param scheduleJob
	 * @throws SchedulerException
	 */
	public static void addJob(ScheduleJob job) throws SchedulerException {
		if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {
			return;
		}
		Scheduler scheduler = schedulerFactoryBean.getScheduler();
		logger.info("添加调度任务：{}", JSON.toJSONString(job));
		TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
		CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
		// 不存在，创建一个
		if (null == trigger) {
			Class clazz = ScheduleJob.CONCURRENT_IS.equals(job.getIsConcurrent()) ? QuartzJobFactory.class
					: QuartzJobFactoryDisallowConcurrentExecution.class;
			JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup())
					.usingJobData("data", job.getJobData()).build();
			jobDetail.getJobDataMap().put("scheduleJob", job);
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
			trigger = TriggerBuilder.newTrigger().withDescription(job.getJobId().toString())
					.withIdentity(job.getJobName(), job.getJobGroup()).withSchedule(scheduleBuilder).build();
			scheduler.scheduleJob(jobDetail, trigger);
		} else {
			// Trigger已存在，那么更新相应的定时设置
			CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
 
			// 按新的cronExpression表达式重新构建trigger
			trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).usingJobData("data", job.getJobData())
					.withSchedule(scheduleBuilder).build();
 
			// 按新的trigger重新设置job执行
			scheduler.rescheduleJob(triggerKey, trigger);
		}
		/*  暂停任务
		if ("0".equals(job.getIsConcurrent())) {
			JobKey jobKey = JobKey.jobKey(job.getJobName(), job.getJobGroup());
			scheduler.pauseJob(jobKey);
		}
		*/
	}
 
}